package com.pr.makfilm.core.cmp.window;

import com.pr.makfilm.core.cmp.web.AbstractBootstrapComponent;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.attributes.AjaxCallListener;
import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton;
import org.apache.wicket.feedback.FeedbackMessage;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.util.visit.IVisit;
import org.apache.wicket.util.visit.IVisitor;

import java.util.List;
import java.util.Random;

public abstract class AbstractWindow<T extends Object> extends Panel
{
   private static final long serialVersionUID = 8955482927887494778L;

   protected Form form;

   protected IModel<String> headerModel;

   protected String domId;

   public AbstractWindow(String id, IModel<T> model, IModel<String> headerModel)
   {
      this(id, model, headerModel, false);
   }

   public AbstractWindow(String id, IModel<T> model, IModel<String> headerModel, boolean generateDomId)
   {
      super(id, model);
      setOutputMarkupId(true);
      this.headerModel = headerModel;
      domId = id + (generateDomId ? new Random().nextInt() : "");
   }

   @Override
   protected void onInitialize()
   {
      super.onInitialize();
      WebMarkupContainer container = new WebMarkupContainer("container");
      setOutputMarkupPlaceholderTag(true);
      container.add(new AttributeModifier("id", domId));
      add(container);
      form = new Form<Void>("form");
      AjaxButton submitLink = getSubmitLink("save", form);
      if (submitLink != null)
      {
         form.add(submitLink);
         form.setDefaultButton(submitLink);
      }
      form.add(getCancelLink("cancel"));
      container.add(getCancelLink("close"));
      container.add(form);
      container.add(new Label("header", headerModel));
   }

   protected AjaxLink getCancelLink(String id)
   {
      return new AjaxLink(id)
      {
         @Override
         public void onClick(AjaxRequestTarget target)
         {
            AbstractWindow.this.onCancel(target);
         }
      };
   }

   protected AjaxButton getSubmitLink(String id, final Form<Void> form)
   {
      IndicatingAjaxButton submitLink = new IndicatingAjaxButton(id, form)
      {
         private static final long serialVersionUID = -703188740715674542L;

         @Override
         protected void onSubmit(AjaxRequestTarget target, Form<?> form)
         {
            AbstractWindow.this.onSubmit(target, form);
            AbstractWindow.this.onAfterSubmit(target);
            beforeClose(target);
         }

         @Override
         protected void onError(AjaxRequestTarget target, Form<?> form)
         {
            target.add(form);
            AbstractWindow.this.onError(target, form);
         }

         @Override
         protected void updateAjaxAttributes(AjaxRequestAttributes attributes)
         {
            super.updateAjaxAttributes(attributes);
            AjaxCallListener myAjaxCallListener = new AjaxCallListener()
            {
               @Override
               public CharSequence getBeforeHandler(Component component)
               {
                  return "var x=document.getElementById('submit-" + domId + "');x.className += ' disabled';";
               }
            };
            attributes.getAjaxCallListeners().add(myAjaxCallListener);

//            form.visitChildren(AbstractBootstrapComponent.class, new BootstrapComponentVisitor(attributes));
         }
      };
      submitLink.setOutputMarkupId(true);
      submitLink.setMarkupId("submit-" + domId);
      return submitLink;
   }

   protected void onAfterSubmit(AjaxRequestTarget target)
   {
   };

   protected void resetState()
   {
   };

   public void show(AjaxRequestTarget target)
   {
      resetState();
      target.add(AbstractWindow.this);

      if (getFocusComponent() != null)
      {
         Component component = getFocusComponent() instanceof AbstractBootstrapComponent ? ((AbstractBootstrapComponent) getFocusComponent())
                 .getField() : getFocusComponent();
         target.appendJavaScript("$('#" + domId + "').unbind('shown');");
         target.appendJavaScript("$('#" + domId + "').on('shown', function () { $('#" + component.getMarkupId()
                 + "').focus(); });");
      }
      target.appendJavaScript("$('#" + domId + "').modal('show');");
   }

   protected void beforeClose(AjaxRequestTarget target)
   {
      target.appendJavaScript("$('#" + domId + "').modal('hide');");
      target.appendJavaScript("$('.modal-backdrop').hide();");
   }

   public abstract void onSubmit(AjaxRequestTarget target, Form<?> form);

   public void onError(AjaxRequestTarget target, Form<?> form)
   {
   };

   protected void setHeader(String header)
   {
      headerModel.setObject(header);
   }

   public void onCancel(AjaxRequestTarget target)
   {
      beforeClose(target);
   }

   protected void clearMessages()
   {
      form.visitChildren(new IVisitor<Component, Void>()
      {
         @Override
         public void component(Component object, IVisit<Void> visit)
         {
            if (object instanceof FeedbackPanel)
            {
               FeedbackPanel feedbackPanel = (FeedbackPanel) object;
               List<FeedbackMessage> feedbackMessages = feedbackPanel.getFeedbackMessagesModel().getObject();
               if (!feedbackMessages.isEmpty())
               {
                  for (FeedbackMessage feedbackMessage : feedbackMessages)
                  {
                     feedbackMessage.markRendered();
                  }
               }
            }
         }
      });
   }

   protected Component getFocusComponent()
   {
      return null;
   }

   @Override
   protected void onDetach()
   {
      super.onDetach();
      headerModel.detach();
      form.detach();
   }

   public T getObject()
   {
      return (T) getDefaultModelObject();
   }
//   private static final long serialVersionUID = 8955482927887494778L;
//
//   protected Form form;
//
//   protected IModel<String> headerModel;
//
//   public AbstractWindow(String id, IModel<String> headerModel)
//   {
//      super(id, headerModel);
//      this.headerModel = headerModel;
//      setOutputMarkupId(true);
//
//      WebMarkupContainer container = new WebMarkupContainer("container");
//      container.add(new AttributeModifier("id", id));
//      add(container);
//
//      form = new Form<Void>("form");
//      AjaxButton submitLink = getSubmitLink(form);
//      if (submitLink != null)
//      {
//         form.add(submitLink);
//         form.setDefaultButton(submitLink);
//      }
//      form.add(getCancelLink());
//      container.add(form);
//      container.add(new Label("header", new PropertyModel<String>(this, "header")));
//   }
//
//   protected AjaxLink getCancelLink()
//   {
//      AjaxLink link = new AjaxLink("cancel")
//      {
//         @Override
//         public void onClick(AjaxRequestTarget target)
//         {
//            AbstractWindow.this.onCancel(target);
//         }
//      };
//      return link;
//   }
//
//   protected AjaxButton getSubmitLink(Form<Void> form)
//   {
//      AjaxButton ajaxLink = new AjaxButton("ajaxLink", form)
//      {
//         private static final long serialVersionUID = -703188740715674542L;
//
//         @Override
//         protected void onSubmit(AjaxRequestTarget target, Form<?> form)
//         {
//            AbstractWindow.this.onSubmit(target, form);
//            beforeClose(target);
//         }
//
//         @Override
//         protected void onError(AjaxRequestTarget target, Form<?> form)
//         {
//            target.add(form);
//            AbstractWindow.this.onError(target, form);
//         }
//      };
//      return ajaxLink;
//   }
//
//   public void show(AjaxRequestTarget target)
//   {
//      target.add(AbstractWindow.this);
//      target.appendJavaScript("$('#" + getId() + "').modal('show');");
//   }
//
//   protected void beforeClose(AjaxRequestTarget target)
//   {
//      target.appendJavaScript("$('#" + getId() + "').modal('hide');");
//      target.appendJavaScript("$('.modal-backdrop').remove();");
//   }
//
//   public abstract void onSubmit(AjaxRequestTarget target, Form<?> form);
//
//   public abstract void onError(AjaxRequestTarget target, Form<?> form);
//
//   public void onCancel(AjaxRequestTarget target)
//   {
//      beforeClose(target);
//   }
//
//   public String getHeader()
//   {
//      return header;
//   }
//
//   public void setHeader(String header)
//   {
//      this.header = header;
//   }
}
